package cn.bdqn.service.user;

import cn.bdqn.dao.Role.User_RoleMapper;
import cn.bdqn.dao.User.UserMapper;
import cn.bdqn.dto.LoginDTO;
import cn.bdqn.dto.LoginUser;
import cn.bdqn.dto.UserDTO;
import cn.bdqn.pojo.Role.SysUserRole;
import cn.bdqn.pojo.User.User;
import cn.bdqn.service.Role.RoleService;
import cn.bdqn.service.Role.User_RoleService;
import cn.bdqn.utils.Json;
import cn.bdqn.utils.JwtUtil;
import cn.bdqn.utils.Page;
import cn.bdqn.utils.RedisCache;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
//<<<<<<< HEAD
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
//=======
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
//>>>>>>> origin/master
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;

import static cn.bdqn.utils.RedisConstants.*;

@Service
@Slf4j
public class UserService extends ServiceImpl<UserMapper,User> {

    BCryptPasswordEncoder bCryptPasswordEncoder = new BCryptPasswordEncoder();

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    UserMapper userMapper;

    @Autowired
    private User_RoleMapper roleMapper;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private RoleService roleService;

    @Autowired
    private User_RoleService userRoleService;

    QueryWrapper wrapper=new QueryWrapper();

    //登录方法
    public Json login(LoginDTO user){
        Authentication authenticate =
                //参数为 第一个账号(手机号) 第二个密码
                //这里会转到 AdminLoginService 里面的实现类型 实现类 会转为 LoginUser类
                authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(user.getPhone(), user.getPassword()));
        if (Objects.isNull(authenticate)){
            //如果为空 抛出异常
            Json.fall("用户名或密码错误");
        }

        log.info("------------执行成功+++用户->"+authenticate.getPrincipal()+"--------------");
        LoginUser users = (LoginUser) authenticate.getPrincipal();
        //获取用户userid使用jwt 工具类加密
        String userId = users.getUser().getUserId().toString();
        System.out.println(userId);
        String jwt = JwtUtil.createJWT(userId);
        log.info("---------------userid 加密后为--->"+jwt+"------------");
        //存入redsi  第一个前缀 第二个 主题 第三个 时间 第四个时间类型
        redisCache.setCacheObject(LOGIN_USER_TOKEN+userId,users,LOGIN_USER_TTL, TimeUnit.MINUTES);
        UserDTO userDTO = BeanUtil.copyProperties(users.getUser(), UserDTO.class);
        HashMap<String, Object> map = new HashMap<>();
        map.put("token",jwt);
        map.put("user",userDTO);
        //把token 和转换后的user信息 返还给前端
        return Json.ok(map);
    }

    /**
     *
     * 用户注册方法
     * @param user
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Integer insertUser(User user) {
        user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
        int insert = userMapper.insert(user);
        int role=roleService.insertUserAndRole(new SysUserRole(user.getUserId()));
        if(insert>0&&role>0){
            return insert;
        }
        return 0;
    }

    /**
     * 用户修改方法
     * @param user
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Integer updateUser(User user){
        user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
        return userMapper.updateById(user);
    }

    /**
     * 停用单个用户
     * @param id
     * @param state
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public Integer deleteUser(Integer id,Integer state) {
        Integer integer = userMapper.updateUser(id,state);
        Integer integer1 = userRoleService.updateUserRole(id);
        if(integer>0&&integer1>0){
            return integer;
        }
        return 0;
    }

    /**
     * 查询方法
     * @param curr  该参数必传
     * @param size  该参数必传
     * @param name
     * @param role
     * @param phone
     * @return
     */
    public PageInfo selectUser(Integer curr, Integer size,String name,String role,String phone,String startTime,String endTime,String sex,String email,String state) {
        PageHelper.startPage(curr,size);
        List<User> users = userMapper.selectUser(name,role,phone,startTime,endTime,sex,email,state);
        PageInfo info=new PageInfo(users);
        return info;
    }
    //批量停用
    public Integer updateUsers(List<Integer> ids){
        return userMapper.updateUsers(ids);
    }
    //批量启用
    public Integer enabled(List<Integer> ids){return userMapper.enabled(ids);}
    /**
     *
     * 根据id查询单个用户
     * @param userId 必须
     * @return
     */
    public User getUserById(Integer userId){

        wrapper.eq("user_id",userId);
        return userMapper.selectOne(wrapper);
    }


    /**
     * 退出登录
     * @return
     */
    public Json logout() {
        //获取 hoder里面用户信息
        LoginUser loginUser =
                (LoginUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        Integer userid = loginUser.getUser().getUserId();
        //删除redis 的值
        redisCache.deleteObject(LOGIN_USER_TOKEN+userid);
        log.info("-------------删除用户id为:"+userid+"redis的缓存-------------");
        return Json.ok("退出登录成功");
    }

    /**
     * 查询全部管理员
     * @param pageNum
     * @param pageSize
     * @param name
     * @param phone
     * @param roleId
     * @return
     */
    public Json getAllAdmin(Integer pageNum,Integer pageSize,String name,String phone ,Integer roleId) {
        if (roleId == null || roleId < 1000 ){
            roleId = null;
        }
        PageHelper.startPage(pageNum, pageSize);
        List<User> users = userMapper.selectAdmin(name,phone,roleId);
        PageInfo<User> userPageInfo = new PageInfo<>(users);
        return Json.ok(userPageInfo);
    }

    @Transactional(rollbackFor = Exception.class)
    public Json deleteAdmin(Integer userid, Integer state) {
        if (state == 1){
            state = 0;
        }else if (state == 0){
            state = 1;
        }
        Boolean aBoolean = userMapper.deleteAdminById(userid, state);
        if (aBoolean == true){
            return Json.ok();
        }
        return Json.fall("修改失败");
    }
    //查询用户总数
    public Long selectUserByCount() {
        wrapper.eq("is_del",1);
       return userMapper.selectCount(wrapper);
    }
    //查询今日新增用户数量
    public Integer NewUsersToday() {
       return userMapper.NewUsersToday();
    }
    //查询作日新增用户数量
    public Integer YesterdayUsersToday() {
        Integer integer = userMapper.YesterdayUsersToday();
        return integer;
    }

    //查询本月新增用户
    public Integer monthTheRegistered(){
        return userMapper.monthTheRegistered();
    }

    //根据时间查询用户
    public Integer selectUserByTime(String createTime){
        return userMapper.selectUserByTime(createTime);
    }

    public Map<String,Integer> queryUserOverviewData(){
        //查询用户总数
        Long total = selectUserByCount();
        //查询今日用户注册量
        Integer NewUsers = NewUsersToday();
        //查询昨日用户注册量
        Integer Yesterday = YesterdayUsersToday();
        //查询本月新增用户
        Integer monthTheRegistered = monthTheRegistered();
        Map  map=new HashMap();
        map.put("NewUsersToday",NewUsers);
        map.put("YesterdayTotal",Yesterday);
        map.put("month",monthTheRegistered);
        map.put("userTotal",total.intValue());
        return map;
    }


    @Transactional(rollbackFor = Exception.class)
    public Json inserAdmin(User user) {
        String encode = bCryptPasswordEncoder.encode(user.getPassword());
        user.setPassword(encode);
        log.info("------注册user===>"+user+"-----------");
        int insert = userMapper.insert(user);
        if (insert <= 0 ){
            return Json.fall("添加失败");
        }
        User userByPhone = userMapper.getUserByPhone(user.getPhone());
        log.info("------------------添加成功->"+userByPhone+"------------------------");
        Integer userId = userByPhone.getUserId();
        Integer c =  roleMapper.insertRoel(userId,user.getRoleId());
        if (c <= 0){
            return Json.fall("添加失败");
        }
        return Json.ok();
    }
    //查询所有用户，返回用户的姓名，id
    public List<User> selectAllUser() {
        List<User> users = userMapper.selectList(new QueryWrapper<User>().eq("is_del",1));
        return users;
    }


    public User loginByPhone(String phone){
        return userMapper.getUserByPhone(phone);
    }

}
